from CNode import *
class CList(object):
    __slots__=['__size', '__first', '__last', '__current', '__iter']
    # Constructor
    def __init__(self):
        self.__size = 0
        self.__first = None
        self.__last = None
        self.__current = None
        self.__iter = None
    # Recollir dades de la llista
    def getData(self):
        if self.isEmpty():
            raise IndexError, 'La lista esta vacia'
        else:
            return self.__current.getData()
    def getSize(self):
        return self.__size
    def getLast(self):
        if self.isEmpty():
            raise IndexError, 'La lista esta vacia'
        else:
            return self.__last.getData()
    def getFirst(self):
        if self.isEmpty():
            raise IndexError, 'La lista esta vacia'
        else:
            return self.__first.getData()
    # Funcions per moure el __current
    def First(self):
        self.__current = self.__first
    def Last(self):
        self.__current = self.__last
    def Left(self):
        if self.__current == self.__first:
            raise IndexError, "Primer element"
        else:
            self.__current = self.__current.getLeft()
    def Right(self):
        if self.__current == self.__last:
            raise IndexError, "Ultim element"
        else:
            self.__current = self.__current.getRight()
    # Funcions per comprovar l'estat de la llista
    def isLast(self):
		return self.__current == self.__last
    def isFirst(self):			
		return self.__current == self.__first
    def isEmpty(self):
        return self.__size==0
    # Funcio per convertir la llista en una cadena de caracters.
    def __str__(self):
        auxnode=self.__first
        result = ''
        while auxnode != None:
            result += str(auxnode) + ','
            auxnode = auxnode.getRight()
        return result 
    # Funcions d'insercio/esborrat de dades
    def Insert(self, data, flag = 1):
        if self.isEmpty():
            self.__current = CNode(data,None,None) #Crea el nou node
            self.__first = self.__current
            self.__last = self.__current
        else:
            if flag == 0: #Per a flag==0 afegim a l'esquerre del node actual
                auxnode = CNode(data,self.__current.getLeft(),self.__current)#Creem el nou node en una variable auxiliar situant a l'esquerre, el q te a l'esquerre el node actual, y a la dreta el node actual
                self.__current.setLeft(auxnode) #Situem el nou node a l'esquerre del node actual
                if self.__current == self.__first: #Hem de mirar si el node actual era el primer, ja que llavors el nou node sera ara el primer
                    self.__first  = auxnode
                else: #Si no era el primer, hem de situar a dreta del node que abans tenia el node actual a la dreta, el nou node.
                    auxnode.getLeft().setRight(auxnode)
            if flag == 1: #Per a flag==1 afegim a la dreta del node actual
                auxnode = CNode (data,self.__current,self.__current.getRight())
                self.__current.setRight(auxnode)
                if self.__current == self.__last:
                    self.__last = auxnode
                else:
                    auxnode.getRight().setLeft(auxnode)
            self.__current = auxnode
        self.__size+=1
    def Remove(self):
        if self.isEmpty():
            raise IndexError, 'La lista esta vacia'
        else:
            if self.__size == 1:
                self.__current = None
                self.__last = None
                self.__first = None
            else:
                if self.__current == self.__first:
                    self.__current = self.__current.getRight()
                    self.__current.setLeft(None)
                    self.__first = self.__current
                elif self.__current == self.__last:
                    self.__current = self.__current.getLeft()
                    self.__current.setRight(None)
                    self.__last = self.__current
                else:
                    aux = self.__current.getRight()
                    aux.setLeft(self.__current.getLeft())
                    aux = self.__current.getLeft()
                    aux.setRight(self.__current.getRight())
                    self.__current = self.__current.getLeft()
            self.__size-=1        
    # Iteradors
    def __iter__(self):
        self.__iter = self.__first
        return self 
    def next(self):
        try:
            aux = self.__iter.getData()
            self.__iter = self.__iter.getRight()
            return aux
        except:
            raise StopIteration;
